package hxy.dragon.ktor.data

import kotlinx.serialization.Contextual
import kotlinx.serialization.InternalSerializationApi
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.SerializationException
import kotlinx.serialization.builtins.ListSerializer
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.descriptors.buildClassSerialDescriptor
import kotlinx.serialization.descriptors.element
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.json.JsonDecoder
import kotlinx.serialization.json.JsonPrimitive
import kotlinx.serialization.json.int
import kotlinx.serialization.serializer

/**
 * @description
 * @author HOX4SGH
 * @date 2024/7/19
 */
@Serializable
data class BaseResponse(
    var code: Int,
    var msg: String,
    @Contextual
    @Serializable(with = DataSerializer::class)
    var data: Any? // 可以为空
)

/**
 * 自定义序列化与反序列化器
 */
object DataSerializer : KSerializer<Any?> {
    override val descriptor: SerialDescriptor = buildClassSerialDescriptor("Data") {
        element<String>("data") // 会根据实际类型变化
    }

    @OptIn(InternalSerializationApi::class)
    override fun serialize(encoder: Encoder, value: Any?) {
        when (value) {
            null -> encoder.encodeNull()
            is String -> {
                if (value.isNotBlank()) {
                    encoder.encodeString(value) // 如果是字符串，直接序列化为字符串
                } else {
                    encoder.encodeNull()
                }
            }

            is Int -> encoder.encodeInt(value) // 如果是整数，直接序列化为整数
            is ArrayList<*> ->
                encoder.encodeSerializableValue(
                    ListSerializer(DataSerializer),
                    value.filterNotNull() // 过滤空值
                )

            else -> {
                val actualSerializer =
                    encoder.serializersModule.getContextual(value::class) ?: value::class.serializer()
                encoder.encodeSerializableValue(actualSerializer as KSerializer<Any>, value)
            }
        }
    }

    override fun deserialize(decoder: Decoder): Any? {
        val input = decoder as? JsonDecoder ?: throw SerializationException("Expected Json input")
        val jsonElement = input.decodeJsonElement()

        return when {
            jsonElement is JsonPrimitive -> {
                val primitive = jsonElement.content
                if (jsonElement.isString) {
                    primitive // 处理字符串
                } else {
                    jsonElement.int // 处理整数
                }
            }

            else -> null // 处理其他类型或没有数据的情况
        }
    }
}